home *** CD-ROM | disk | FTP | other *** search
- /* switches.c - terminal switch control
- *****************************************************************************
- expecTerm version 1.0 beta
- Mark Weissman
- Christopher Matheus
- Copyright 1992 by GTE Laboratories Incorporated.
-
- Portions of this work are in the public domain. Permission to use,
- copy, modify, and distribute this software and its documentation for
- any purpose and without fee is hereby granted, provided that the above
- copyright notice appear in all copies and that both the copyright
- notice and warranty disclaimer appear in supporting documentation, and
- that the names of GTE Laboratories or any of their entities not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
-
- GTE disclaims all warranties with regard to this software, including
- all implied warranties of merchantability and fitness for a particular
- purpose, even if GTE Laboratories Incorporated knows about the
- purpose. In no event shall GTE be liable for any special, indirect or
- consequential damages or any damages whatsoever resulting from loss of
- use, data or profits, whether in an action of contract, negligence or
- other tortuous action, arising out of or in connection with the use or
- performance of this software.
-
- This code is based on and may include parts of Don Libes' expect code:
- expect written by: Don Libes, NIST, 2/6/90
- Design and implementation of expect was paid for by U.S. tax
- dollars. Therefore it is public domain. However, the author and NIST
- would appreciate credit if this program or parts of it are used.
- ******************************************************************************
-
- Written by: Mark Weismann and Chris Matheus May 1992
-
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <tcl.h>
- #include "win.h"
- #include "global.h"
- #include "command.h"
- #include "translate.h"
-
- extern int fd_max;
-
- /*ARGSUSED*/
- static int
- cmdTermInfo(clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int m = -1, n = -1, writep = 0;
- char nstrings;
- char **strings;
- char buf[BUFSIZ], modearg = 's', mode;
-
- /* get spawn id if any */
- nstrings = argc - 1;
- strings = argv+1;
- if (nstrings < 1) goto usage_error;
- if (streq(*strings,"-i")) {
- --nstrings; ++strings;
- if (nstrings < 1) goto usage_error;
- m = atoi(*strings);
- --nstrings; ++strings;
- if (nstrings < 1) goto usage_error;
- }
- if (streq(*strings,"-type") || streq(*strings,"-local") || streq(*strings,"-transmit")) {
- writep = 1;
- if (streq(*strings,"-type")) modearg = 's';
- else if (streq(*strings,"-local")) modearg = 'L';
- else modearg = 'X';
- --nstrings; ++strings;
- if (nstrings < 1) goto usage_error;
- }
-
- /* get master fd */
- if ((m == -1) && (update_master(&m) == 0)) return(TCL_ERROR);
- if (m == -1) return(TCL_ERROR);
- else if (m <= 2) {
- tcl_error("%s: Invalid Master: %d",argv[0]);
- return(TCL_ERROR);
- }
- if (!SetSessionFromFD(m)) {
- tcl_error("%s: Master: %d Not Associated with emulator.",argv[0],m);
- return(TCL_ERROR);
- }
- for (n=0; n<nstrings; ++n) {
- extern char *LookupCap();
- char *string = LookupCap(Session->term, strings[n]);
- mode = string[strlen(string)+1];
- if (!string) {
- tcl_error("%s: Could Not find Terminfo Capability for: {%s}.",argv[0], strings[n]);
- return(TCL_ERROR);
- }
- if (strchr("sXL", mode)) {
- *buf = '\0';
- if (mode == 'X') strcpy(buf, "-transmit ");
- if (mode == 'L') strcpy(buf, "-local ");
- FixEscapes(buf+strlen(buf), string);
- string = buf;
- }
- Tcl_AppendElement(interp, string, 0);
- }
- for (n=0; writep && n<nstrings; ++n) {
- extern char *LookupCap();
- char *string = LookupCap(Session->term, strings[n]);
- if (!string) {
- tcl_error("%s: Could Not find TERMINFO Capability for: {%s}.",argv[0], strings[n]);
- return(TCL_ERROR);
- }
- /* Look at type code hidden after the string
- If its 'b' (boolean), or 'n' (numeric) don't send it to terminal
- If its 's' (string) then defer to mode from argument.
- If its 'X' (Transmit string) then terminal said to Transmit this string.
- If its 'L' (Local string) then terminal said to execute this string locally.
- */
- mode = string[strlen(string)+1];
- if (!strchr("sXL", mode)) continue;
- if (mode == 's') mode = modearg;
- if (mode == 'L') {
- char olocal = Session->term->Local;
- Session->term->Local=1;
- Write(Session->fd, string, strlen(string));
- Session->term->Local=olocal;
- }
- else if (mode == 'X') {
- write(Session->fd, string, strlen(string));
- if (Session->term->Local) {
- char cr='\r', nl='\n';
- write(Session->fd, &cr, 1);
- if (Session->term->bool_hpAutoLinefeed==1) write(Session->fd, &nl, 1);
- }
- }
- else
- Write(Session->fd, string, strlen(string));
- }
- return(TCL_OK);
-
- usage_error:
- tcl_error("usage: %s [-i spawn_id] [-type | -local | -transmit] [terminfo-capability-name]+", argv[0]);
- return(TCL_ERROR);
- }
-
- /*ARGSUSED*/
- static int
- cmdSetMaster(clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int m = -1, n = -1, terminalp, i, refreshp=0, was_terminalp;
- char tempbuf[80];
- extern char in_curses;
- extern int loguser;
-
- /* get spawn id if any */
- for (i=1;i<argc;i++) {
- if (streq(argv[i],"-i")) {
- if (argc == ++i) goto usage_error;
- m = atoi(argv[i]);
- break;
- }
- }
-
- /* get master fd */
- if ((m == -1) && (update_master(&m) == 0)) return(TCL_ERROR);
- if (m == -1) return(TCL_ERROR);
- else if (m <= 2) {
- tcl_error("%s: Invalid Master: %d",argv[0]);
- return(TCL_ERROR);
- }
- was_terminalp = SetSessionFromFD(m);
- n=m;
-
- /* parse rest of arguments */
- for (i=1;i<argc;i++) {
- if (streq(argv[i],"-i")) i++;
- else if (streq(argv[i],"-next")) {
- while (TRUE) {
- if (++n > fd_max) n=0;
- if ((n==m) || (!is_user(n) && fs[n].pid && (fs[n].flags & FD_VALID))) break;
- }
- }
- else if (streq(argv[i],"-prev")) {
- while (TRUE) {
- if (--n < 0) n=fd_max;
- if ((n==m) || (!is_user(n) && fs[n].pid && (fs[n].flags & FD_VALID))) break;
- }
- } else if (streq(argv[i],"-refresh")) {
- refreshp = 1;
- } else goto usage_error;
- }
-
- terminalp = SetSessionFromFD(n);
- SetCurrSession();
- sprintf(interp->result,"%d", n);
-
- if (refreshp) ResetWindow();
- if (!terminalp) {
- if (was_terminalp && loguser) system("clear");
- sprintf(tempbuf,"\r\nResuming Master: %d, pid: %d\r\n", n, fs[n].pid);
- write(1,tempbuf,strlen(tempbuf));
- }
- sprintf(tempbuf,"%d",n);
- Tcl_SetVar(interp,"spawn_id",tempbuf,0);
- return(TCL_OK);
-
- usage_error:
- tcl_error("usage: %s [-i spawn_id | -next | -prev] [-refresh]", argv[0]);
- return(TCL_ERROR);
- }
-
- /*ARGSUSED*/
- static int
- cmdStatusLine(clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int m = -1, i, refreshp = 0;
- static char *prev = "-default";
- char *text = NULL;
- WinbarP = 1;
- if ((m == -1) && (update_master(&m) == 0)) return(TCL_ERROR);
- if (m == -1) return(TCL_ERROR);
- SetSessionFromFD(m);
- for(i=1; i < argc; ++i) {
- extern char *GetStatusLine();
- if (streq(argv[i],"-refresh")) {
- refreshp = 1;
- if (!text) text = GetStatusLine();
- }
- else if (streq(argv[i],"-default")) {
- prev = "-default";
- text = WIN_DEFAULT_WINBAR;
- }
- else if (streq(argv[i],"-none")) {
- prev = "-none";
- refreshp = WinbarP = 0;
- }
- else if ((streq(argv[i],"-message")) && ((i+1)<argc)) {
- text = argv[++i];
- prev = "-message";
- }
- else if (*argv[i] != '-') {
- prev = "-message";
- text = argv[i];
- }
- else {
- tcl_error("usage: %s [-i spawn_id] [-refresh] [-none | -default | -message string]", argv[0]);
- return(TCL_ERROR);
- }
- }
- if (refreshp) UpdateWindow(text);
- else SetStatusLine(text);
- sprintf(interp->result,"%s", prev);
- if (prev[1] == 'm') /* message */
- Tcl_AppendElement(interp, GetStatusLine(), 0);
- return(TCL_OK);
- }
-
- /*ARGSUSED*/
- static int
- cmdTermSwitch(clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int m = -1, i;
- int refreshp=0;
- char temp_buf[32], *tmpstatus = NULL;
- extern char *Strdup();
-
- /* get spawn id if any */
- for (i=1;i<argc;i++) {
- if (streq(argv[i],"-i")) {
- if (argc == ++i) goto usage_error;
- m = atoi(argv[i]);
- break;
- }
- }
-
- /* get master fd */
- if ((m == -1) && (update_master(&m) == 0)) return(TCL_ERROR);
- if (m == -1) return(TCL_ERROR);
- else if (m <= 2) {
- tcl_error("%s: Invalid Master: %d",argv[0]);
- return(TCL_ERROR);
- }
- if (!SetSessionFromFD(m)) {
- tcl_error("spawn_id %d not associated with a terminal emulator.", m);
- return(TCL_ERROR);
- }
-
- /* parse rest of arguments */
- for (i=1;i<argc;i++) {
- if (streq(argv[i],"-i")) {
- i++;
- } else if (streq(argv[i],"-refresh")) {
- refreshp = 1;
- } else if (streq(argv[i],"-echo")) {
- if (i+1 < argc) {
- if (streq(argv[i+1],"-get")) {
- i++;
- } else if (streq(argv[i+1],"-on")) {
- Session->echop = 1;
- i++;
- } else if (streq(argv[i+1],"-off")) {
- Session->echop = 0;
- i++;
- } else if (streq(argv[i+1],"-toggle")) {
- Session->echop = (Session->echop? 0 : 1);
- i++;
- }
- }
- sprintf(temp_buf,"%d",Session->echop);
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (streq(argv[i],"-tabspace")) {
- if (i+1 < argc) {
- if (streq(argv[i+1],"-get")) {
- i++;
- } else if (streq(argv[i+1],"-on")) {
- Session->tabspacep = 1;
- i++;
- } else if (streq(argv[i+1],"-off")) {
- Session->tabspacep = 0;
- i++;
- } else if (streq(argv[i+1],"-toggle")) {
- Session->tabspacep = (Session->tabspacep? 0 : 1);
- i++;
- }
- }
- sprintf(temp_buf,"%d",Session->tabspacep);
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (streq(argv[i],"-all_breaks")) {
- if (i+1 < argc) {
- if (streq(argv[i+1],"-get")) {
- i++;
- } else if (streq(argv[i+1],"-on")) {
- Session->breaksp = 1;
- i++;
- } else if (streq(argv[i+1],"-off")) {
- Session->breaksp = 0;
- i++;
- } else if (streq(argv[i+1],"-toggle")) {
- Session->breaksp = (Session->breaksp? 0 : 1);
- i++;
- }
- }
- sprintf(temp_buf,"%d",Session->tabspacep);
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (streq(argv[i],"-crnl")) {
- if (i+1 < argc) {
- if (streq(argv[i+1],"-get")) {
- i++;
- } else if (streq(argv[i+1],"-on")) {
- Session->crnlp = 1;
- i++;
- } else if (streq(argv[i+1],"-off")) {
- Session->crnlp = 0;
- i++;
- } else if (streq(argv[i+1],"-toggle")) {
- Session->crnlp = (Session->crnlp? 0 : 1);
- i++;
- }
- }
- sprintf(temp_buf,"%d",Session->crnlp);
- Tcl_AppendElement(interp, temp_buf, 0);
-
- /* log option */
- } else if (streq(argv[i],"-log") || streq(argv[i],"-rawlog")) {
- char *file=NULL, buf[128];
- int raw = (argv[i][1] == 'r'), logp = 2;
- char *mode = "w";
- FILE **Session_log;
- char **Session_log_filename;
-
- for (++i;i<argc;i++) {
- if ((streq(argv[i],"-file") && (++i<argc)) || (argv[i][0] != '-')) {
- logp = 1;
- if (NULL == (argv[i] = Tcl_TildeSubst(interp,argv[i])))
- return TCL_ERROR;
- file = argv[i];
- } else if (streq(argv[i],"-get")) {
- logp = 2;
- } else if (streq(argv[i],"-raw")) {
- raw = 1;
- } else if (streq(argv[i],"-on")) {
- logp = 1;
- } else if (streq(argv[i],"-off")) {
- logp = -1;
- } else if (streq(argv[i],"-toggle")) {
- logp = 0;
- } else if (streq(argv[i],"-append")) {
- mode = "a";
- } else { --i; break; }
- }
-
- if (raw) {
- Session_log = &(Session->raw_log);
- Session_log_filename = &(Session->raw_log_filename);
- } else {
- Session_log = &(Session->cooked_log);
- Session_log_filename = &(Session->cooked_log_filename);
- }
-
- if (logp == 2) { /* if just "getting" state info */
- sprintf(temp_buf,"%s", (*Session_log ? *Session_log_filename : "0"));
- Tcl_AppendElement(interp, temp_buf, 0);
- }
- else {
- logp = (logp ? (logp + 1) : (!*Session_log));
-
- if (logp) { /* turn logging on */
- if (file) {
- if (*Session_log_filename) free(*Session_log_filename);
- *Session_log_filename = (char *)Strdup(file);
- }
- if (!*Session_log_filename) {
- file = buf;
- sprintf(buf,"%s/ExpectLog.%s%d", ExpectLogDir, (raw ? "raw" : ""), m);
- *Session_log_filename = (char *)Strdup(file);
- }
- *Session_log = fopen(*Session_log_filename,mode);
- /* printf("Logfile: %s\n",*Session_log_filename); */
- sprintf(buf,"%s Log: %s", (raw ? "Raw" : "Cooked"),
- *Session_log_filename);
- if (tmpstatus) free(tmpstatus);
- tmpstatus = Strdup(buf);
- sprintf(temp_buf,"%s", (*Session_log ? *Session_log_filename : "0"));
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (*Session_log) { /* turn logging off */
- if (!raw) BFLUSH(0);
- fclose(*Session_log);
- *Session_log = NULL;
- sprintf(temp_buf,"%s", (*Session_log ? *Session_log_filename : "0"));
- Tcl_AppendElement(interp, temp_buf, 0);
- } else if (raw)
- Tcl_AppendElement(interp, "0 Raw Logging already off", 0);
- else
- Tcl_AppendElement(interp, "0 Logging already off", 0);
- }
- } else goto usage_error;
- }
- if (refreshp) {
- UpdateWindow(tmpstatus);
- if (tmpstatus) {
- SetStatusLine(WIN_DEFAULT_WINBAR);
- free(tmpstatus);
- }
- }
- return(TCL_OK);
-
- usage_error:
- tcl_error("usage: %s [-i spawn_id] [-refresh] [[-echo|-crnl|-tabspace|-all_breaks] [-on|-off|-toggle|-get]] \
- [[-log|-rawlog] [-append] [-on|-off|-toggle|-file string]", argv[0]);
- return(TCL_ERROR);
- }
-
- /*ARGSUSED*/
- static int
- cmdEmulate(clientData, interp, argc, argv)
- Tcl_Interp *interp;
- ClientData clientData;
- int argc;
- char **argv;
- {
- int i = 1;
- int m = -1;
- int rows = 0;
- int cols = 0;
- char *emulate = NULL;
- struct f *fp;
-
- for(i=1; i < argc; ++i) {
- if (streq(argv[i],"-i")) {
- if (++i == argc) goto usage_error;
- else m = atoi(argv[i]);
- }
- else if (streq(argv[i],"-term")) {
- if (++i == argc) goto usage_error;
- else emulate = argv[i];
- }
- else if (streq(argv[i],"-rows")) {
- if (++i == argc) goto usage_error;
- else rows = atoi(argv[i]);
- }
- else if (streq(argv[i],"-cols")) {
- if (++i == argc) goto usage_error;
- else cols = atoi(argv[i]);
- }
- else if (streq(argv[i],"-get")) {
- }
- else if ('0' <= *argv[i] && (*argv[i] <= '9'))
- m = atoi(argv[i]);
- else emulate = argv[i];
- }
- if ((m == -1) && (update_master(&m) == 0)) return(TCL_ERROR);
- if (m == -1) return(TCL_ERROR);
- if (is_user(m)) {
- tcl_error("cannot emulate with self - set spawn_id to a spawned process");
- return(TCL_ERROR);
- }
- else if (m <= 2) {
- tcl_error("%s: Invalid Master: %d",argv[0]);
- return(TCL_ERROR);
- }
- if (emulate) {
- if (!EmulateTerminal(emulate, m, rows, cols)) {
- fp = fd_to_f(m);
- tcl_error("FAILURE: %s -i %d %s", argv[0], m, emulate);
- return(TCL_ERROR);
- }
- }
- SetSessionFromFD(m);
- sprintf(interp->result,"%s", ((Session && Session->term->type)?Session->term->type:"0"));
- return(TCL_OK);
-
- usage_error:
- tcl_error("usage: %s [-i spawn_id] [-get|[-term] term]", argv[0]);
- return(TCL_ERROR);
- }
-
- #define deleteProc (void (*)())0
- void
- init_switch_interpreter(interp)
- Tcl_Interp *interp;
- {
- extern int cmdScreenInfo();
-
- Tcl_SetVar(interp,"term_type","vt100",0);
- Tcl_SetVar(interp,"nonasci_char", "#",0);
- Tcl_SetVar(interp,"screen_quiet", "0.0",0);
- Tcl_SetVar(interp,"term_echo", ECHOP_DEFAULT,0);
- Tcl_SetVar(interp,"term_crnl", CRNLP_DEFAULT,0);
- Tcl_SetVar(interp,"term_tabspace", TABSPACEP_DEFAULT,0);
- Tcl_SetVar(interp,"term_breaks", BREAKS_DEFAULT,0);
-
- Tcl_CreateCommand(interp,"screen_info",
- cmdScreenInfo,(ClientData)0,deleteProc);
- Tcl_CreateCommand(interp,"emulate",
- cmdEmulate,(ClientData)0,deleteProc);
- Tcl_CreateCommand(interp,"term_switch",
- cmdTermSwitch,(ClientData)0,deleteProc);
- Tcl_CreateCommand(interp,"set_master",
- cmdSetMaster,(ClientData)0,deleteProc);
- Tcl_CreateCommand(interp,"status_line",
- cmdStatusLine,(ClientData)0,deleteProc);
- Tcl_CreateCommand(interp,"term_info",
- cmdTermInfo,(ClientData)0,deleteProc);
- }
-